package com.example.forum2.services.impl;

import com.example.forum2.common.AppResult;
import com.example.forum2.common.ResultCode;
import com.example.forum2.dao.UserMapper;
import com.example.forum2.exception.ApplicationException;
import com.example.forum2.model.User;
import com.example.forum2.services.IUserService;
import com.example.forum2.utils.MD5Util;
import com.example.forum2.utils.StringUtil;
import com.example.forum2.utils.UUIDUtil;
import lombok.extern.slf4j.Slf4j;
import lombok.val;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;

@Service
@Slf4j
//实现IUserService中的方法
public class UserServiceImpl implements IUserService {
    @Resource
    private UserMapper userMapper;
    public void createNormalUser(User user) {
//        1.这里要先对传递过来的user的属性进行校验
        if (user == null || StringUtil.isEmpty(user.getUsername()) || StringUtil.isEmpty(user.getPassword()) || StringUtil.isEmpty(user.getNickname())) {
//            打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
//         抛出一个自己创建的异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//       2.非空校验之后就可以进行调用了,调用之前要先进行注入,service层调用的是dao层的方法,dao层操纵的是数据库
//          因为已经进行了注入,所以可以直接进行调用
        User exitUsers=userMapper.selectByUserName(user.getUsername());
//        判断查询的用户是否存在
        if(exitUsers!=null){
//          如果用户已经存在,直接打印用户存在即可
         log.info(ResultCode.FAILED_USER_EXISTS.toString());
//           然后进行抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
        }
//        3.开始时进行了不为空的校验,之后进行了的校验确定了用户不存在
//        新增用户,设备默认值
        user.setGender((byte) 2);
        user.setArticleCount(0);
        user.setIsAdmin((byte)0);
        user.setState((byte)0);
        user.setDeleteState((byte)0);
//        然后是设置日期
        Date date=new Date();
        user.setCreateTime(date);
        user.setUpdateTime(date);
//        进行校验完成之后,可以进行写入数据库
        int row=userMapper.insertSelective(user);
//      这里要检查数据库是否插入成功
        if(row!=1){
//            这里是新增用户失败
//            打印日志
            log.info(ResultCode.FAILED_CREATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_CREATE));
        }
//        新增成功之后,打印日志
        log.info("新增用户成功,username="+user.getUsername());
    }
//    这里实现查询功能
    public User selectByUserName(String name){
//              首先还是对参数进行非空校验
        if(StringUtil.isEmpty(name)){
//            打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//     如果参数不为空,返回结果即可
        return userMapper.selectByUserName(name);

    }
//    接下来写登录接口.
    public User login(String name,String password){
//1.还是要进行非空校验
        if(StringUtil.isEmpty(name) ||StringUtil.isEmpty(password)){
//            打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
//    抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//        参数校验用过之后,就要调用接口
        val user = userMapper.selectByUserName(name);
//        这里首先要对查询结果做非空校验
        if(user==null){
//            打印日志
            log.warn(ResultCode.FAILED_LOGIN.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
//查询结果校验之后,要对密码进行校验,先生成密码,然后进行比较即可
        String enxryPassword= MD5Util.md5Salt(password,user.getSalt());
//        现在进行比较即可

        if(!enxryPassword.equals(user.getPassword())){
            log.warn(ResultCode.FAILED_LOGIN.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_LOGIN));
        }
//        正确之后,返回即可,返回用户信息
        return user;
    }
//根据id,查询用户信息
    public User selectById(Long id){
//        一种是用过session来查询,所以在controller层就可以进行返回,传递到service层的肯定就是根据id查询的,因此首先进行参数校验
        if(id==null){
//            打印日志
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
//        调用dao层,进行操作即可
        User user = userMapper.selectByPrimaryKey(id);
        return user;

    }

    @Override
    public void addOneArticleCountById(Long id) {
//        还是要对Id,进行判断
        if(id<=0||id==null){
//            打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        User user=userMapper.selectByPrimaryKey(id);
//        对user进行判断
        if(user==null){
//            打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
//        接下来是更新用户的贴子数
        User user1=new User();
        user1.setId(user.getId());
        user1.setArticleCount(user.getArticleCount()+1);
        int row=userMapper.updateByPrimaryKeySelective(user1);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }

    @Override
    public void subOneArticleCountById(Long id) {
        //        还是要对Id,进行判断
        if(id<=0||id==null){
//            打印日志
            log.warn(ResultCode.FAILED_BOARD_ARTICLE_COUNT.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_BOARD_ARTICLE_COUNT));
        }
        User user=userMapper.selectByPrimaryKey(id);
//        对user进行判断
        if(user==null){
//            打印日志
            log.warn(ResultCode.ERROR_IS_NULL.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.ERROR_IS_NULL));
        }
        User user1=new User();
        user1.setId(user.getId());
        user1.setArticleCount(user.getArticleCount()-1);
        if(user1.getArticleCount()<0){
            user1.setArticleCount(0);
        }
        int row=userMapper.updateByPrimaryKeySelective(user1);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }

    }

    @Override
    public void modifyInfo(User user) {
//       首先做非空校验
        if(user==null||user.getId()==null||user.getId()<=0){
//          打印日志
            log.warn(ResultCode.FAILED_USER_BANNEDS.toString());
//            抛出异常
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_BANNEDS));

        }
//        接着检验用户是否存在
        User user1=userMapper.selectByPrimaryKey(user.getId());
        if(user1==null){
//            打印日志
            log.warn(ResultCode.FAILED_USER_NOT_EXISTS.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_NOT_EXISTS));
        }
//        定义一个标志位,当标志位为falses时,表示未通过.
        boolean checkAttr=false;
//        对传入的数据进行判断
        User updateUser=new User();
//        设置用户id,
        updateUser.setId(user.getId());
//        对每一个参数进行校验
        if(!StringUtil.isEmpty(user.getUsername())&&!user.getUsername().equals(user1.getUsername())){
//            只有当满足这两个条件时,才进行更新,更新用户名时需要进行唯一性判断
            User checkUser=userMapper.selectByUserName(user.getUsername());
            if(checkUser!=null){
//                用户已经存在
                log.warn(ResultCode.FAILED_USER_EXISTS.toString());
                throw new ApplicationException(AppResult.failed(ResultCode.FAILED_USER_EXISTS));
            }
//            数据库中没有找到相应用户时,才进行更新
            updateUser.setUsername(user.getUsername());
            checkAttr=true;
        }
//        校验昵称
        if(!StringUtil.isEmpty(user.getNickname())&&!user.getNickname().equals(user1.getNickname())){
            updateUser.setNickname(user.getNickname());
            checkAttr=true;
        }
//        校验性别
        if(user.getGender()!=null&&!user.getGender().equals(user1.getGender())){
            updateUser.setGender(user.getGender());
            checkAttr=true;
        }
//    校验邮箱
       if(!StringUtil.isEmpty(user.getEmail())&&!user.getEmail().equals(user1.getEmail())){
           updateUser.setEmail(user.getEmail());
           checkAttr=true;
       }
//       校验电话号码
        if(!StringUtil.isEmpty(user.getPhoneNum())&&!user.getPhoneNum().equals(user1.getPhoneNum())){
            updateUser.setPhoneNum(user.getPhoneNum());
            checkAttr=true;
        }
//校验个人简介
        if(!StringUtil.isEmpty(user.getRemark())&&!user.getRemark().equals(user1.getRemark())){
            updateUser.setRemark(user.getRemark());
            checkAttr=true;
        }
//校验完毕,根据标志位来判断是否可以执行更新操作

        if(checkAttr == false){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString()+updateUser.getUsername());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//执行更新操作
       int row=userMapper.updateByPrimaryKeySelective(updateUser);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED));

        }
    }

    @Override
    public void modifyPassword(Long id, String newPassword, String oldPassword) {
//        首先对参数进行非空校验
        if(id==null||id<=0||StringUtil.isEmpty(newPassword)||StringUtil.isEmpty(oldPassword)){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw  new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//        根据id查询用户信息,并进行校验
        User user=userMapper.selectByPrimaryKey(id);
        if(user==null||user.getDeleteState()==1){
            log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
            throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//        检验老密码是否正确

        String oldpassword1=MD5Util.md5Salt(oldPassword,user.getSalt());
        if(!oldpassword1.equalsIgnoreCase(user.getPassword())){
               log.warn(ResultCode.FAILED_PARAMS_VALIDATE.toString());
               throw new ApplicationException(AppResult.failed(ResultCode.FAILED_PARAMS_VALIDATE));
        }
//        生成盐,生新的密码
        String salt2= UUIDUtil.UUID_32();
//        生成密码
        String newpassword2=MD5Util.md5Salt(newPassword,salt2);
        User updateUSer=new User();
        updateUSer.setId(user.getId());
        updateUSer.setSalt(salt2);
        updateUSer.setPassword(newpassword2);
        Date date=new Date();
        updateUSer.setUpdateTime(date);
        int row = userMapper.updateByPrimaryKeySelective(updateUSer);
        System.out.println(row);
        if(row!=1){
            log.warn(ResultCode.FAILED.toString());
            throw  new ApplicationException(AppResult.failed(ResultCode.FAILED));
        }
    }
}
